﻿// 引入所需的命名空间
using CoinTrader.OKXCore.Entity;
using CoinTrader.OKXCore.Enum;
using CoinTrader.Strategies.Runtime;
using System;
using System.Collections.Generic;

namespace CoinTrader.Strategies
{
    /// <summary>
    /// 合约策略基类，所有针对合约的策略均需要从这个基类派生
    /// </summary>
    public abstract class SwapStrategyBase : TradeStrategyBase
    {
        // 合约交易对信息实例
        protected InstrumentSwap instrument;

        // 重写策略类型属性，标识为合约策略
        protected override StrategyType StrategyType => StrategyType.Swap;

        // 合约策略运行时实例
        private SwapStrategyRuntime swapRuntime;

        /// <summary>
        /// 获取最大杠杆倍数
        /// </summary>
        /// <returns>最大杠杆倍数</returns>
        protected uint MaxLever => swapRuntime.GetMaxLever();

        /// <summary>
        /// 获取资金费率
        /// </summary>
        /// <returns>当前资金费率</returns>
        protected double FundingRate => swapRuntime.GetFundingRate();

        /// <summary>
        /// 初始化策略
        /// </summary>
        /// <param name="instId">交易对ID</param>
        /// <returns>初始化是否成功</returns>
        public override bool Init(string instId)
        {
            // 调用基类初始化方法
            if (!base.Init(instId))
                return false;

            // 将基础instrument转换为合约instrument类型
            instrument = instrumentBase as InstrumentSwap;

            // 将运行时对象转换为合约策略运行时类型
            swapRuntime = runtime as SwapStrategyRuntime;

            // 如果instrument转换失败（虽然此处没有具体处理逻辑）
            if (instrument == null)
            {
                // 可能需要错误处理逻辑
            }

            // 返回初始化成功
            return true;
        }

        /// <summary>
        /// 设置杠杆
        /// </summary>
        /// <param name="side">持仓方向</param>
        /// <param name="mode">保证金模式(逐仓和全仓)</param>
        /// <param name="lever">杠杆倍数</param>
        public void SetLever(PositionType side, SwapMarginMode mode, uint lever)
        {
            // 调用运行时设置杠杆方法
            swapRuntime.SetLever(side, mode, lever);
        }

        /// <summary>
        /// 市价平仓（按持仓ID）
        /// </summary>
        /// <param name="id">持仓ID</param>
        protected void ClosePosition(long id)
        {
            // 调用运行时平仓方法
            swapRuntime.ClosePosition(id);
        }

        /// <summary>
        /// 市价平仓（按持仓ID和合约张数）
        /// </summary>
        /// <param name="id">持仓ID</param>
        /// <param name="size">合约张数</param>
        protected void ClosePosition(long id, int size)
        {
            // 调用运行时平仓方法，指定张数
            swapRuntime.ClosePosition(id, size);
        }

        /// <summary>
        /// 市价平仓（按持仓ID和数量）
        /// </summary>
        /// <param name="id">持仓ID</param>
        /// <param name="amount">数量</param>
        protected void ClosePosition(long id, decimal amount)
        {
            // 调用运行时平仓方法，指定数量
            swapRuntime.ClosePosition(id, amount);
        }

        /// <summary>
        /// 获取当前合约品种下的所有持仓
        /// </summary>
        /// <returns>持仓列表</returns>
        protected IList<Position> GetPositions()
        {
            // 调用运行时获取持仓方法
            return swapRuntime.GetPositions();
        }

        /// <summary>
        /// 返回某个方向下的所有持仓
        /// </summary>
        /// <param name="type">持仓方向类型</param>
        /// <returns>指定方向的持仓列表</returns>
        public IList<Position> GetPositions(PositionType type)
        {
            // 创建持仓列表存储结果
            IList<Position> positions = new List<Position>();

            // 遍历所有持仓，筛选符合条件的
            this.EachPosition((pos) => {
                // 筛选指定方向且交易对匹配的持仓
                if (pos.SideType == type && string.Compare(pos.InstId, InstId) == 0)
                {
                    positions.Add(pos);
                }
            });

            // 返回筛选后的持仓列表
            return positions;
        }

        /// <summary>
        /// 获取指定ID的持仓
        /// </summary>
        /// <param name="id">持仓ID</param>
        /// <returns>指定ID的持仓对象</returns>
        protected Position GetPosition(long id)
        {
            // 调用运行时获取指定持仓方法
            Position position = swapRuntime.GetPosition(id);
            return position;
        }

        /// <summary>
        /// 遍历所有持仓
        /// </summary>
        /// <param name="callback">处理每个持仓的回调函数</param>
        protected void EachPosition(Action<Position> callback)
        {
            // 调用运行时遍历持仓方法
            swapRuntime.EachPosition(callback);
        }

        /// <summary>
        /// 市价创建仓位（按数量）
        /// </summary>
        /// <param name="side">方向</param>
        /// <param name="amount">数量</param>
        /// <param name="mode">仓位模式</param>
        /// <returns>返回非0则成功（订单ID）</returns>
        protected long CreatePosition(PositionType side, decimal amount, SwapMarginMode mode)
        {
            // 调用运行时创建仓位方法，返回订单ID
            return swapRuntime.CreatePosition(side, amount, mode);
        }

        /// <summary>
        /// 市价创建仓位（按合约张数）
        /// </summary>
        /// <param name="side">方向</param>
        /// <param name="size">合约张数</param>
        /// <param name="mode">仓位模式</param>
        /// <returns>返回非0则成功（订单ID）</returns>
        protected long CreatePosition(PositionType side, int size, SwapMarginMode mode)
        {
            // 调用运行时创建仓位方法，返回订单ID
            return swapRuntime.CreatePosition(side, size, mode);
        }
    }
}